#!/bin/bash
# 打包脚本依赖: bc zip
# sudo apt-get install -y bc zip
function pack_clear(){
    echo "清除编译文件"
    #   收尾: 删除文件
    # out_dir=$(pwd)/out
    # rm ${out_dir}/*.bin
    # rm ${out_dir}/*.elf
    # rm ${out_dir}/*.csv
    # rm ${out_dir}/*.tar.gz
    # rm ${out_dir}/*.txt
}
function pack(){
    # 请根据自己的环境配置以下参数
    sdkconfig=sdkconfig
    # SDKVersion=$(cat sdkconfig | grep -m 1 Project | cut -d ' ' -f 7)
    # env_path=~/esp/v$SDKVersion/esp-idf
    # env_path=~/esp/v5.2/esp-idf
    env_path=~/esp/v5.5/esp-idf
    # 请根据自己的环境配置以上参数
    # project=$(cat CMakeLists.txt | grep "project(" | grep -v "#" | grep -oP '\(\K[^)]+')
    project=$(cat CMakeLists.txt | grep "project(" | grep -v "#" | grep -oP '\(\K[^)]+')
    version=$(cat version.txt)
    _python=python
    _esptool=$env_path/components/esptool_py/esptool/esptool.py
    work_dir=$(pwd)
    out_dir=$(pwd)/bin/${version}
    export BUILD_PRODUCTION=1
    BUILD_PRODUCTION=1
    if [ "$1" == "test" ]; then
        export BUILD_PRODUCTION=0
        BUILD_PRODUCTION=0
    fi

    if [ -f "${env_path}/export.sh" ]; then
        echo "导入编译环境"
        echo
        . ${env_path}/export.sh >/dev/null
    else
        echo "编译环境文件不存在, 请检查...... ${env_path}/export.sh"
        exit 1
    fi

    if [ ! -d "${out_dir}" ]; then
        echo "生成输出目录 ${out_dir}"
        mkdir -p ${out_dir}
    fi
    rm -rf ${out_dir}/*.bin
    rm -rf ${out_dir}/*.elf
    rm -rf ${out_dir}/*.txt

    firmware_name="esp_bat_pb"
    CHIP_TAGET=$(cat $sdkconfig | grep CONFIG_IDF_TARGET=)
    CHIP_TAGET=${CHIP_TAGET/CONFIG_IDF_TARGET=\"/}
    CHIP_TAGET=${CHIP_TAGET/\"/}
    pack_time=$(date "+%Y%m%d%H%M")
    st=$(echo "$(date +%s.%N)" | bc)
    #  ${CHIP_TAGET^^} 转大写
    firmware_name=${firmware_name}-${CHIP_TAGET^^}

    echo
    echo "-----------------------------------------------------------------------------------------------------------------------------"
    echo "| SDK Version   : $SDKVersion"
    echo "| project name  : $project"
    echo "| firmware name : $firmware_name"
    echo "| Version       : $version"
    echo "| Out Directory : $out_dir"
    echo "| Build Time    : $pack_time"
    echo "-----------------------------------------------------------------------------------------------------------------------------"
    echo

    echo
    echo "项目名称: ${firmware_name} 固件名称: ${project} 时间: ${pack_time}"

    #   编译升级版本文件
    #   生成测试使用的升级文件
    export BUILD_UPDATE_FILE=1
    BUILD_UPDATE_FILE=1
    newVersionHihgt=$(echo $version | awk '{split($1, arr, "."); print arr[1]}')
    newVersionLow=$(echo $version | awk '{split($1, arr, "."); print arr[2]}')
    newVersionLow=$(echo $newVersionLow + 1 | bc)
    newVersion=$(echo $newVersionHihgt.$newVersionLow)
    echo "CONFIG_APP_PROJECT_VER_FROM_CONFIG=y" >> $sdkconfig
    echo "CONFIG_APP_PROJECT_VER=\"${newVersion}\"" >> $sdkconfig
    sync
    echo
    echo "编译升级固件版本 : $(cat version.txt) => $newVersion"
    echo
    #   重新编译所有文件
    idf.py fullclean > /dev/null
    #   编译并复制升级固件
    idf.py build > /dev/null
    sed -i "s/CONFIG_APP_PROJECT_VER_FROM_CONFIG=y//g" $sdkconfig
    sed -i "s/CONFIG_APP_PROJECT_VER=\"${newVersion}\"//g" $sdkconfig
    if [ ! -n "$(ls ./build/*.elf)" ]; then
        echo "编译失败, 请检查源码"
        exit 0
    fi
    project=$(basename $(ls ./build/*.elf))
    project=${project%.*}
    # echo "复制升级文件 ${firmware_name}_app_update_${pack_time}.bin"
    echo "复制升级文件 update.bin"
    sync
    sleep 1
    # cp ./build/$project.bin ${out_dir}/${firmware_name}_app_update_${pack_time}.bin
    cp ./build/$project.bin ${out_dir}/update.bin
    sync
    sleep 1

    #   编译当前版本文件
    export BUILD_UPDATE_FILE=0
    BUILD_UPDATE_FILE=0
    #   复位固件版本
    # echo $version > version.txt
    echo
    echo "编译正常固件版本 : $(cat version.txt)"
    echo
    idf.py build > /dev/null
    if [ ! -n "$(ls ./build/*.elf)" ]; then
        echo "编译失败, 请检查源码"
        exit 0
    fi
    sync
    sleep 1
    # cp ./build/$project.bin ${out_dir}/${firmware_name}_app_v${version}_${pack_time}.bin
    cp ./build/$project.bin ${out_dir}/app.bin
    #   生成 单bin 烧录文件
    cd build
    #   添加其它分区烧录镜像
    echo
    # echo "打包 测试部 使用 烧录 文件: ${firmware_name}_test_v${version}_${pack_time}.bin"
    echo "打包 测试部 使用 烧录 文件: test.bin"
    #   打包测试部固件
    # $_python $_esptool --chip $CHIP_TAGET merge_bin -o ${out_dir}/${firmware_name}_test_v${version}_${pack_time}.bin @flash_args >/dev/null
    $_python $_esptool --chip $CHIP_TAGET merge_bin -o ${out_dir}/test.bin @flash_args >/dev/null
    cd $work_dir
    sync
    sleep 1

    # idf.py build >/dev/null
    # if [ ! -n "$(ls ./build/*.elf)" ]; then
    #     echo "编译失败, 请检查源码"
    #     exit 0
    # fi

    #   获取其它分区固件路径
    echo
    echo "生成分区信息表......"
    partition_files=$(ls ./build/*.bin | grep -v $project.bin | grep -v ota_data*)
    #   生成分区表信息文本
    # partition_info=${out_dir}/${firmware_name}_partition_info_${pack_time}.csv
    partition_info=${out_dir}/partitions.csv
    idf.py partition-table | grep -A 12 -B 0 "# ESP-IDF Partition Table" >${partition_info}
    cat ${partition_info} | tail -n +4 | head -n $(wc -l <${partition_info}) >${partition_info}
    #   检查是否存在第二个更新分区
    have_ota1=$(cat ${partition_info} | grep app | wc -l)

    cd build
    #   添加分区信息
    cat ${partition_info}
    add_partition=""
    for partition in ${partition_files}; do
        partition_name=$(basename ${partition})
        partition_name=${partition_name%.*}
        offset=$(cat ${partition_info} | grep ${partition_name} | tail -n 1 | awk -F, '{printf $4}')
        if [ ! -n "$(cat flash_args | grep ${partition_name}.bin)" ]; then
            add_partition=$(echo -e "$add_partition\n${offset} ${partition_name}.bin")
        fi
    done
    add_ota1=""
    if [ "$have_ota1" -gt "1" ]; then
        have_ota1=$(cat ${partition_info} | grep app | tail -n 1 | awk -F, '{printf $4}')
        sed -i -e "s/${project}.bin/&\n$have_ota1 ${project}.bin/" flash_args
        add_ota1="1"
    fi
    if [ -n "${add_partition}" ]; then
        echo ${add_partition} >>flash_args
        cat flash_args
    fi
    echo
    # production_bin=${out_dir}/${firmware_name}_production_v${version}_${pack_time}.bin
    production_bin=${out_dir}/production.bin
    echo "打包 生产部 使用 烧录 文件: ${production_bin}"
    #   打包生产部固件
    $_python $_esptool --chip $CHIP_TAGET merge_bin -o ${production_bin} @flash_args >/dev/null
    #   收尾:移除添加的信息
    echo
    echo -e "移除信息: ${add_partition}"
    for partition in ${add_partition}; do
        if [ -n "$(cat flash_args | grep ${partition})" ]; then
            sed -i -e "/${partition}/d" flash_args
        fi
    done
    if [ -n "$add_ota1" ]; then
        echo "$have_ota1 ${project}.bin"
        sed -i -e "/${have_ota1}/d" flash_args
    fi

    echo
    cd ..
    # cp ./build/bootloader/bootloader.elf ${out_dir}/${firmware_name}_bootloader_v${version}_${pack_time}.elf
    # cp ./build/bootloader/bootloader.bin ${out_dir}/${firmware_name}_bootloader_v${version}_${pack_time}.bin
    # cp ./build/partition_table/partition-table.bin ${out_dir}/${firmware_name}_partition_table_v${version}_${pack_time}.bin
    # cp ./build/ota_data_initial.bin ${out_dir}/${firmware_name}_ota_data_initial_v${version}_${pack_time}.bin
    # cp ./build/$project.elf ${out_dir}/${firmware_name}_app_v${version}_${pack_time}.elf
    cp ./build/$project.elf ${out_dir}/app.elf
    python ./tools/esp_delta_ota_patch_gen.py create_patch --chip ${CHIP_TAGET} --base_binary ${out_dir}/app.bin --new_binary ${out_dir}/update.bin --patch_file_name ${out_dir}/update_patch.bin
    git log --pretty=format:'%as%C(auto)%d %s' >${out_dir}/update_log.txt
    for file in ${partition_files}; do
        file_name=$(basename ${file})
        echo "拷贝文件: ${file} 到 "
        # echo ${out_dir}/${firmware_name}_${file_name%.*}_v${version}_${pack_time}.bin
        # cp ${file} ${out_dir}/${firmware_name}_${file_name%.*}_v${version}_${pack_time}.bin
        echo ${out_dir}/${file_name%.*}.bin
        cp ${file} ${out_dir}/${file_name%.*}.bin
    done
    echo
    sync
    sleep 1

    # echo
    # echo "打包源码......"
    # dir_name=$(basename $(pwd))
    # echo "当前目录 $dir_name"
    # cd ..
    # #   复制调试击升级可能需要的文件
    # #   排除目录"
    # # tar -zcvf ${out_dir}/test.tar.gz \
    # # code_file=${out_dir}/${firmware_name}_code_v${version}_${pack_time}.tar.gz
    # code_file=${out_dir}/code.tar.gz
    # tar -zcvf ${code_file} \
    #     --exclude="*.git*" \
    #     --exclude="*.old" \
    #     --exclude="*.lock" \
    #     --exclude="*.log" \
    #     --exclude="*testdata*" \
    #     --exclude="$dir_name/.*" \
    #     --exclude="*/luatos" \
    #     --exclude=$dir_name/backup \
    #     --exclude=*/build \
    #     --exclude=$dir_name/out \
    #     $dir_name >/dev/null
    # cd $dir_name

    # #   生成说明文件
    # echo "生产部使用的固件  : ${firmware_name}_production_v${version}_${pack_time}.bin" >${out_dir}/README.txt
    # echo "测试部使用的固件  : ${firmware_name}_test_v${version}_${pack_time}.bin" >>${out_dir}/README.txt
    # echo "测试更新所需固件  : ${firmware_name}_app_update_${pack_time}.bin" >>${out_dir}/README.txt
    # echo "固件调试所需文件  : ${firmware_name}_app_v${version}_${pack_time}.elf" >>${out_dir}/README.txt
    # echo "分区手动烧录地址  : ${firmware_name}_partition_info_${pack_time}.csv" >>${out_dir}/README.txt
    # echo "当前版本源代码    : ${firmware_name}_code_v${version}_${pack_time}.tar.gz" >>${out_dir}/README.txt
    # echo "源码更新记录      : update_log.txt" >>${out_dir}/README.txt
    # echo >>${out_dir}/README.txt
    # echo "以下固件烧录地址为: 0x0" >>${out_dir}/README.txt
    # echo "${firmware_name}_production_v${version}_${pack_time}.bin 和 ${firmware_name}_test_v${version}_${pack_time}.bin" >>${out_dir}/README.txt
    # echo >>${out_dir}/README.txt
    # echo "测试部使用的固件 包含 : bootloader & partition_table & ota_data_initial & app" >>${out_dir}/README.txt
    # echo "生产部使用的固件 包含 : bootloader & partition_table & ota_data_initial & app(ota_0) & app(ota_1) & storage & www" >>${out_dir}/README.txt
    # echo "其余 BIN 文件 为 手动烧录指定分区 / OTA 所需" >>${out_dir}/README.txt

    # #   打包文件
    # # pack_end="tar"
    # pack_end="zip"
    # # pack_file=${out_dir}/${firmware_name}_v${version}_${pack_time}.${pack_end}
    # pack_file=${out_dir}/pack.${pack_end}
    # cd ${out_dir}
    # zip -q -o ${pack_file} *.txt *.bin *.elf *.csv *.tar.gz >/dev/null
    # # tar -cvf ${firmware_name}_${pack_time}.${pack_end} *.txt *.bin *.elf *.csv *.tar.gz >/dev/null
    # cd ..

    # #   结束通报
    # if [ ! -f "${pack_file}" ]; then
    #     echo "无法打包文件到 "
    # else
    #     # echo
    #     # echo "👇👇👇👇👇👇👇👇👇👇👇👇👇👇 README.txt 👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇"
    #     # cat ${out_dir}/README.txt
    #     # echo "👆👆👆👆👆👆👆👆👆👆👆👆👆👆 README.txt 👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆"
    #     echo
    #     echo "任务完成, 打包文件: "
    # fi
    et=$(echo "$(date +%s.%N)" | bc)
    diff=$(echo "$et-$st" | bc)

    # echo ${pack_file}
    # ls -lh ${pack_file}
    ls -lh ${out_dir}
    echo "累计耗时： $diff S"

    #   收尾: 删除文件
    echo "清除编译文件"
    rm ${out_dir}/*.csv
}